package site.xuqing.nobean;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * 假数据提供者
 *
 * @author Created by xuqing on 2023/1/13 11:24
 */
public class FakeDataProvider {
    /**
     * 列表需要生成多少条数据
     */
    public static final int LIST_SIZE = 4;
    
    /**
     * 根据传入的类型生成假数据对象
     *
     * @param clazz 模板类
     * @param <T>   数据对象
     * @return 数据
     */
    public <T> T getFakeObjectData(Class<T> clazz) {
        try {
            T t = clazz.newInstance();
            Field[] fields = t.getClass().getDeclaredFields();
            for (Field field : fields) {
                String type = field.getGenericType().toString();
                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }
                if (type.equals("class java.lang.String")) {
                    field.set(t, "test");
                } else if (type.equals("class java.lang.Integer")) {
                    field.set(t, 0);
                } else if (type.equals("class java.lang.Short")) {
                    field.set(t, 0.1);
                } else if (type.equals("class java.lang.Double")) {
                    field.set(t, 0.01);
                } else if (type.equals("class java.lang.Boolean")) {
                    field.set(t, false);
                } else if (type.equals("class java.lang.Byte")) {
                    field.set(t, "C".getBytes());
                } else if (type.equals("class java.lang.Long")) {
                    field.set(t, 0.001);
                } else if (type.equals("class java.lang.Character")) {
                    field.set(t, 'A');
                    //处理List对象
                } else if (List.class.isAssignableFrom(field.getType())) {
                    List<Object> list = new ArrayList<>();
                    for (int i = 0; i < LIST_SIZE; i++) {
                        Type type1 = field.getGenericType();
                        if (type1 instanceof ParameterizedType) {
                            ParameterizedType pt = (ParameterizedType) type1;
                            Class clz = (Class) pt.getActualTypeArguments()[0];
                            list.add(getFakeObjectData(clz));
                        }
                    }
                    field.set(t, list);
                } else {
                    field.set(t, getFakeObjectData(field.getType()));
                }
            }
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 根据传入的类型生成一组假数据
     *
     * @param clazz 模板类
     * @param <T>   数据对象
     * @return 数据
     */
    public <T> List<T> getFakeListData(Class<T> clazz) {
        List<T> list = new ArrayList<>();
        for (int i = 0; i < LIST_SIZE; i++) {
            list.add(getFakeObjectData(clazz));
        }
        return list;
    }
}
